using System;
using System.IO;
using System.Web.UI;

namespace Crawler
{
	/// <summary>
	/// Understands dumping of files in the appropriate directory
	/// </summary>
	public class Dumper : Crawler.IDumper
	{
		private ICentralFactory factory;
		private IDownloadStore downloadStore;
		private IResourceReference resourceReference;
		public int notificationCount = 0;
		public bool dumping = false;
		public IMapper mapper;

		public Dumper()
		{
		}

		public Dumper(ICentralFactory factory)
		{
			this.factory = factory;
			this.downloadStore = factory.GetDownloadStore();
			this.mapper = factory.GetMapper();
		}

		public void CreateDirectoryStructure(string filePath)
		{
			filePath = filePath.Replace(@"/",@"\\"); 
			filePath = filePath.Substring(0,filePath.LastIndexOf('\\')); 
			if (!Directory.Exists(filePath))
				Directory.CreateDirectory(filePath);
		}

		private void CopyDumpableFile(string htmlDump,string destinationPath)
		{
			CreateDirectoryStructure(destinationPath);
			if (!File.Exists(destinationPath))
			{
				try{
					StreamWriter writer = File.CreateText(destinationPath);
					writer.Write(htmlDump);
					writer.Close();
				}catch(Exception e){}
		    }
		}

		private void CopyNonDumpableFile(string sourcePath, string destinationPath)
		{
			CreateDirectoryStructure(destinationPath);
			
			try{
				File.Move(sourcePath, destinationPath);
			}catch (System.IO.FileNotFoundException argExcep){}
		}

		private void CopyFile(IKey key, string destinationPath)
		{
			this.dumping = true;
			resourceReference = downloadStore.GetResource(key);
			if (resourceReference is Dumpable)
				CopyDumpableFile(resourceReference.StreamDump() ,destinationPath);
			else
				CopyNonDumpableFile(resourceReference.StreamDump() ,destinationPath );
			Logger.LogFile(key.ToString()) ;
			dumping = false;
		}

		public void NotifyDumperAboutEntryAdditionToMapper(object sender, EntryAddedToMapperArgs args) {
			this.notificationCount++;
			while(this.notificationCount > 0 && this.dumping == false) 
			{
				Pair keyAndPathPair = mapper.GetNext(); 
				CopyFile(keyAndPathPair.First as IKey, keyAndPathPair.Second as string);
				this.notificationCount--;
			}
		}
	}
}
